/** FASSIT (Forms of Selective Attention in Intelligent Transportation Systems)
 * Computational Creativity and Digital Media
 * Cognitive and Media Systems Group
 * Centre for Informatics and Systems of the University of Coimbra (CISUC)
 *
 * Copyright (c) 2010-2013 University of Coimbra, Portugal
 * All rights reserved.
 */
package poi.Info;

import java.io.Serializable;

import functionsVariables.Constants;

/**
 * This class is used to store all the information about a POI
 * 
 * @author Hernani Costa
 * @version 0.2 date: 12/02/2013
 */

public class POI implements Serializable {
	private static final long serialVersionUID = 1L;
	private String poiName;
	private int poiID;
	private int numCheckins;
	private Price price;
	private Location location;
	private Category category;
	private SubCategory subCategory;
	private DaysOn daysOn;
	private DaysOff daysOff;
	private double surpriseTOcategory, surpriseTOsubCategory, surpriseTOprice, surpriseTOdayOff, surpriseTOschedule, surpriseAverage;
	private double uncertaintyTOcategory, uncertaintyTOsubCategory, uncertaintyTOprice, uncertaintyTOdayOff, uncertaintyTOschedule, uncertaintyAverage;
	private String agentDistanceTOpoi_string;
	private double distanceBetweenUserPOI;

	/**
	 * ------------------------------------------------------------------------
	 * Constructor class
	 * ------------------------------------------------------------------------
	 * 
	 * @param poiName
	 *            - string
	 * @param poiID
	 *            - POI id
	 * @param numCheckins
	 *            - number of Checkin's
	 * @param price
	 *            - POI price
	 * @param location
	 * @param category
	 * @param subCategory
	 * @param daysOn
	 * @param daysOff
	 */
	public POI(String poiName, int poiID, int numCheckins, Price price, Location location, Category category, SubCategory subCategory, DaysOn daysOn,
			DaysOff daysOff) {
		this.poiName = poiName;
		this.poiID = poiID;
		this.numCheckins = numCheckins;
		this.price = price;
		this.location = location;
		this.category = category;
		this.subCategory = subCategory;
		this.daysOn = daysOn;
		this.daysOff = daysOff;
	}

	// ------------------------------------------------------------------------
	// ------------------------GETs and SETs-----------------------------------
	// ------------------------------------------------------------------------

	public String getPoiName() {
		return poiName;
	}

	public String getAgentDistanceTOpoi_string() {
		return agentDistanceTOpoi_string;
	}

	// public void setAgentDistanceTOpoi_string(String
	// agentDistanceTOpoi_string) {
	// this.agentDistanceTOpoi_string = agentDistanceTOpoi_string;
	// }

	public double getDistanceBetweenUserPOI() {
		return distanceBetweenUserPOI;
	}

	public void setDistanceBetweenUserPOI(double distanceBetweenUserPOI) {
		this.distanceBetweenUserPOI = distanceBetweenUserPOI;
	}

	public double getUncertaintyTOcategory() {
		return uncertaintyTOcategory;
	}

	public void setUncertaintyTOcategory(double uncertaintyTOcategory) {
		this.uncertaintyTOcategory = uncertaintyTOcategory;
	}

	public double getUncertaintyTOsubCategory() {
		return uncertaintyTOsubCategory;
	}

	public void setUncertaintyTOsubCategory(double uncertaintyTOsubCategory) {
		this.uncertaintyTOsubCategory = uncertaintyTOsubCategory;
	}

	public double getUncertaintyTOprice() {
		return uncertaintyTOprice;
	}

	public void setUncertaintyTOprice(double uncertaintyTOprice) {
		this.uncertaintyTOprice = uncertaintyTOprice;
	}

	public double getUncertaintyTOdayOff() {
		return uncertaintyTOdayOff;
	}

	public void setUncertaintyTOdayOff(double uncertaintyTOdayOff) {
		this.uncertaintyTOdayOff = uncertaintyTOdayOff;
	}

	public double getUncertaintyTOschedule() {
		return uncertaintyTOschedule;
	}

	public void setUncertaintyTOschedule(double uncertaintyTOschedule) {
		this.uncertaintyTOschedule = uncertaintyTOschedule;
	}

	public double getUncertaintyAverage() {
		uncertaintyAverage = (getUncertaintyTOprice() + getUncertaintyTOschedule() + getUncertaintyTOdayOff()) / 3;
		return uncertaintyAverage;
	}

	public void setUncertaintyAverage(double uncertaintyAverage) {
		this.uncertaintyAverage = uncertaintyAverage;
	}

	public double getSurpriseTOcategory() {
		return surpriseTOcategory;
	}

	public void setSurpriseTOcategory(double surpriseTOcategory) {
		this.surpriseTOcategory = surpriseTOcategory;
	}

	public double getSurpriseTOsubCategory() {
		return surpriseTOsubCategory;
	}

	public void setSurpriseTOsubCategory(double surpriseTOsubCategory) {
		this.surpriseTOsubCategory = surpriseTOsubCategory;
	}

	public double getSurpriseTOprice() {
		return surpriseTOprice;
	}

	public void setSurpriseTOprice(double surpriseTOprice) {
		this.surpriseTOprice = surpriseTOprice;
	}

	public double getSurpriseTOdayOff() {
		return surpriseTOdayOff;
	}

	public void setSurpriseTOdayOff(double surpriseTOdayOff) {
		this.surpriseTOdayOff = surpriseTOdayOff;
	}

	public double getSurpriseTOschedule() {
		return surpriseTOschedule;
	}

	public void setSurpriseTOschedule(double surpriseTOschedule) {
		this.surpriseTOschedule = surpriseTOschedule;
	}

	public double getSurpriseAverage() {
		surpriseAverage = (getSurpriseTOprice() + getSurpriseTOschedule() + getSurpriseTOdayOff()) / 3;
		return surpriseAverage;
	}

	public void setSurpriseAverage(double surpriseAverage) {
		this.surpriseAverage = surpriseAverage;
	}

	public int getPoiID() {
		return poiID;
	}

	public int getNumCheckins() {
		return numCheckins;
	}

	public Price getPrice() {
		return price;
	}

	public Location getLocation() {
		return location;
	}

	public Category getCategory() {
		return category;
	}

	public SubCategory getSubCategory() {
		return subCategory;
	}

	public DaysOff getDaysOff() {
		return daysOff;
	}

	public DaysOn getDaysOn() {
		return daysOn;
	}

	public void setDaysOn(DaysOn daysOn) {
		this.daysOn = daysOn;
	}

	public void setPrice(Price price) {
		this.price = price;
	}

	public void setDaysOff(DaysOff daysOff) {
		this.daysOff = daysOff;
	}

	/**
	 * ------------------------------------------------------------------------
	 * Returns a String with all the POI information
	 * ------------------------------------------------------------------------
	 */
	public String to_String() {
		String info = String.format("Spot[id=%d, name=%s, where=[%s,%s], checkins=%d, price=%s, catID=%d, category=%s, subcatID=%d, subcategory=%s", this
				.getPoiID(), this.getPoiName(), this.getLocation().getLatitude(), this.getLocation().getLongitude(), this.numCheckins, this.getPrice()
				.getAveragePrice(), this.getCategory().getCategoryID(), this.getCategory().getCategoryName(), this.getSubCategory().getSubCategoryID(), this
				.getSubCategory().getSubCategoryName());

		if (!this.getDaysOn().getListDaysOn().isEmpty())
			info += String.format(", \n\tdaysOn=%s,\n\t", this.getDaysOn().to_String());
		else
			info += String.format(", daysOn=null");

		if (!this.getDaysOff().getListDaysOff().isEmpty())
			info += String.format("daysOff=%s", this.getDaysOff().getStringDaysOff());
		else
			info += String.format("daysOff=null");

		info += " ]";
		return info;
	}

	/**
	 * ------------------------------------------------------------------------
	 * Returns a String with all the POI information plus the Selective
	 * Attention Values
	 * ------------------------------------------------------------------------
	 * 
	 */
	public String to_StringSAValues() {
		String info = String
				.format("Spot[id=%d, name=%s, where=[%s,%s], checkins=%d, price=%s, catID=%d, category=%s, subcatID=%d, subcategory=%s\n sTOcategory=%f, sTOsubCategory=%f, sTOprice=%f, sTOdayOff=%f, sTOschedule=%f, sAverage=%f\n uTOcategory=%f, uTOsubCategory=%f, uTOprice=%f, uTOdayOff=%f, uTOschedule=%f, uAverage=%f",
						this.getPoiID(), this.getPoiName(), this.getLocation().getLatitude(), this.getLocation().getLongitude(), this.numCheckins, this
								.getPrice().getAveragePrice(), this.getCategory().getCategoryID(), this.getCategory().getCategoryName(), this.getSubCategory()
								.getSubCategoryID(), this.getSubCategory().getSubCategoryName(), this.getSurpriseTOcategory(), this.getSurpriseTOsubCategory(),
						this.getSurpriseTOprice(), this.getSurpriseTOdayOff(), this.getSurpriseTOschedule(), this.getSurpriseAverage(), this
								.getUncertaintyTOcategory(), this.getUncertaintyTOsubCategory(), this.getUncertaintyTOprice(), this.getUncertaintyTOdayOff(),
						this.getUncertaintyTOschedule(), this.getUncertaintyAverage());

		if (!this.getDaysOn().getListDaysOn().isEmpty())
			info += String.format("\ndaysOn=%s", this.getDaysOn().to_String());
		else
			info += String.format(", daysOn=null");

		if (!this.getDaysOff().getListDaysOff().isEmpty())
			info += String.format(", daysOff=%s", this.getDaysOff().getStringDaysOff());
		else
			info += String.format(", daysOff=null");

		info += "]";
		return info;
	}

	/**
	 * ------------------------------------------------------------------------
	 * Used to provide an example that exercises the functionality of the class.
	 * ------------------------------------------------------------------------
	 * 
	 * @param args
	 */
	public static void main(String args[]) {
		Location location = new Location(9.9, 3.3);
		SubCategory subCategory = new SubCategory("chines", 12);
		Category category = new Category("Restaurante", 43);

		DaysOn dayOn = new DaysOn();
		DaysOff dayOff = new DaysOff();

		Schedule schedule = new Schedule(true, true, false);
		Day day = new Day("segunda", schedule);
		dayOn.addDayOn(day);
		schedule = new Schedule(true, true, false);
		day = new Day("terca", schedule);
		dayOn.addDayOn(day);

		// dayOff.addDaysOff("quarta");
		// dayOff.addDaysOff("quinta");

		Price price = new Price(Constants.getPRICE().get("average"));

		POI poi = new POI("coconetes", 12, 45, price, location, category, subCategory, dayOn, dayOff);
		poi.to_String();

	}

}
